﻿using Business.Base.Model;
using Business.CentrifugalPump.Perf;
using Component;
using Pumptester.ExperimentForms.Base;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace Pumptester.ExperimentForms.CentrifugalPump.Perf
{
    public class CentrifugalPumpPerfChart : IChartDrawer
    {
        private void WriteLogRectangle(string name,double[,] range)
        {
            System.Console.WriteLine("------------------{0}-----------------", name);
            System.Console.WriteLine("({0},{1}),({2},{3}),({4},{5}),({6},{7})",range[0,0], range[0,1], range[1, 0], range[1, 1],range[2,0],range[2,1],range[3,0],range[3,1]);
            System.Console.WriteLine("-----------------------------------");
        }

        public void DrawChart(BaseChartData chartData, UserChart chart)
        {
            CentrifugalPumpPerfChartData chartDatainfo = (CentrifugalPumpPerfChartData)chartData;
            #region 初始化坐标系
            Component.Axis xAxis = new Component.Axis();
            xAxis.Name = "流量(m3/h)";
            xAxis.MaxValue = chartDatainfo.MaxXQAxis;
            xAxis.MinValue = chartDatainfo.MinXQAxis;
            xAxis.SegCount = chartDatainfo.XUnitCount;

            Component.Axis yAxis = new Component.Axis();
            yAxis.Name = "扬程(m)";
            yAxis.MaxValue = chartDatainfo.MaxYHAxis;
            yAxis.MinValue = chartDatainfo.MinYHAxis;
            yAxis.SegCount = chartDatainfo.YUnitCount;


            Component.Axis ySencodAxis = new Component.Axis();
            ySencodAxis.Name = "功率(kw)";
            ySencodAxis.MaxValue = chartDatainfo.MaxYPAxis;
            ySencodAxis.MinValue = chartDatainfo.MinYPAxis;

            Component.Axis yThirdAxis = new Component.Axis();
            yThirdAxis.Name = "效率(%)";
            yThirdAxis.MaxValue = chartDatainfo.MaxYEAxis;
            yThirdAxis.MinValue = chartDatainfo.MinYEAxis;
            #endregion

            #region 初始化坐标系中各种曲线和图形的的颜色，粗细等属性
            Coordinate coordinate = new Coordinate();
            coordinate.XAxis = xAxis;
            coordinate.YAxis = yAxis;



            /*coordinate.AxisDescritionBrush = new SolidBrush(Color.AliceBlue);
            coordinate.AuxiliaryAxisPointBrush = new SolidBrush(Color.White);
            coordinate.AxisPen = new Pen(Color.White);
            coordinate.CurvePen = new Pen(new SolidBrush(Color.AliceBlue),1);
            coordinate.PointBrush = new SolidBrush(Color.Yellow);
            coordinate.LinePen = new Pen(new SolidBrush(Color.AliceBlue), 1);*/

            coordinate.AxisDescritionBrush = new SolidBrush(Color.White);
            coordinate.AuxiliaryAxisPointBrush = new SolidBrush(Color.White);
            coordinate.AxisPen = coordinate.AxisPen  = new Pen(Color.White);
            coordinate.CurvePen =   new Pen(new SolidBrush(Color.White), 1);
            coordinate.PointBrush = new SolidBrush(Color.Yellow);
            coordinate.LinePen = new Pen(new SolidBrush(Color.White), 1);
            coordinate.AuxiliaryBrush= coordinate.AxisDescritionBrush = new SolidBrush(Color.White);


            Coordinate secondCoordinate = new Coordinate();
            secondCoordinate.XAxis = xAxis;
            secondCoordinate.YAxis = ySencodAxis;
            secondCoordinate.CurvePen = secondCoordinate.AxisPen = new Pen(new SolidBrush(Color.Silver), 1);
            secondCoordinate.PointBrush = secondCoordinate.AuxiliaryAxisPointBrush = new SolidBrush(Color.Orange);
            secondCoordinate.AuxiliaryBrush = secondCoordinate.AxisDescritionBrush = new SolidBrush(Color.Silver);

            Coordinate thirdCoordinate = new Coordinate();
            thirdCoordinate.XAxis = xAxis;
            thirdCoordinate.YAxis = yThirdAxis;
            thirdCoordinate.CurvePen = thirdCoordinate.AxisPen = new Pen(new SolidBrush(Color.Gray), 1);
            thirdCoordinate.PointBrush= thirdCoordinate.AuxiliaryAxisPointBrush = new SolidBrush(Color.Red);
            thirdCoordinate.AuxiliaryBrush = thirdCoordinate.AxisDescritionBrush = new SolidBrush(Color.Gray);
            #endregion
            
            #region 初始化采集的点的信息
            for (int i = 0; i < chartDatainfo.InputPoints.Count; i++)
            {
                double q = chartDatainfo.InputPoints[i][0];
                double h = chartDatainfo.InputPoints[i][1];
                double p = chartDatainfo.InputPoints[i][2];
                double e = chartDatainfo.InputPoints[i][3];
                coordinate.Points.Add(new Component.Point(q, h));
                secondCoordinate.Points.Add(new Component.Point(q, p));
                thirdCoordinate.Points.Add(new Component.Point(q, e));

            }
            #endregion

            #region 初始化拟合的曲线
            int pointCount = chartDatainfo.DrawList.Count;
            List<Component.Point> firstPoints = new List<Component.Point>();
            List<Component.Point> secondPoints = new List<Component.Point>();
            List<Component.Point> thirdPoints = new List<Component.Point>();

            for (int i = 0; i < pointCount; i++)
            {
                double[] data = chartDatainfo.DrawList[i];
                double x = data[0];
                double[] qePoints = new double[] { x, data[3] };
                double[] qhPoints = new double[] { x, data[1] };
                double[] qpPoints = new double[] { x, data[2] };

                Component.Point p1 = new Component.Point(qhPoints[0], qhPoints[1]);
                firstPoints.Add(p1);

                Component.Point p2 = new Component.Point(qpPoints[0], qpPoints[1]);
                secondPoints.Add(p2);

                Component.Point p3 = new Component.Point(qePoints[0], qePoints[1]);
                thirdPoints.Add(p3);



            }
            Curve firstCurve = new Curve(firstPoints);
            Curve secondCurve = new Curve(secondPoints);
            Curve thirdCurve = new Curve(thirdPoints);
            coordinate.Curves.Add(firstCurve);
            secondCoordinate.Curves.Add(secondCurve);
            thirdCoordinate.Curves.Add(thirdCurve);
            #endregion

            #region 画出额定流量扬程的与原点连接的直线
            coordinate.Lines.Add(new Line(new Component.Point(0, 0), new Component.Point(chartDatainfo.XMaxHeadinRateHeadQLine, chartDatainfo.YMaxHeadinRateHeadQLine)));
            #endregion


            #region 画出允差范围

            // 画出流量，扬程的允差范围
            if (chartDatainfo.ShowHeadRange && chartDatainfo.FlowHeadRange!=null && chartDatainfo.FlowHeadRange.Length>=1)
            {
                double minY = chartDatainfo.FlowHeadRange[0, 1];
                double maxY = chartDatainfo.FlowHeadRange[1, 1];
                double minX = chartDatainfo.FlowHeadRange[0, 0];
                double maxX = chartDatainfo.FlowHeadRange[2, 0];
                //画出额定流量和扬程的点以及以额定流量，额定扬程下的允差范围
                coordinate.CrossRegion.Add(new CrossRegion(chartDatainfo.XRatedQ, chartDatainfo.YRatedHead,minX,maxX, minY, maxY));
                //coordinate.Rectangles.Add(getRectangle(chartDatainfo.FlowHeadRange));
                //WriteLogRectangle("FlowHeadRange", chartDatainfo.FlowHeadRange);
            }


            #endregion

            #region 画出流量扬程直线与流量扬程测量拟合曲线焦点与X轴垂直的直线
            if(!Double.IsNaN(chartDatainfo.MeasureFlow))
            {
                double measureFlow = chartDatainfo.MeasureFlow;
                double measureHead = chartDatainfo.MeasureHead;
                coordinate.Lines.Add(new Line(new Component.Point(measureFlow, 0), new Component.Point(measureFlow,measureHead)));
            }
                


            #endregion




            chart.FirstCoordinate = coordinate;
            chart.SecondCoordinate = secondCoordinate;
            chart.ThirdCoordinate = thirdCoordinate;


            chart.Refresh();
        }

        private RectangleX getRectangle(double[,] rectangles)
        {
            if (rectangles == null)
            {
                return null;
            }
                if (rectangles.Length != 8)
            {
                throw new Exception("非法Rectangel！");
            }
            double x1 = rectangles[0, 0];
            double y1 = rectangles[0, 1];
            double x2 = rectangles[1, 0];
            double y2 = rectangles[1, 1];
            double x3 = rectangles[2, 0];
            double y3 = rectangles[2, 1];
            double x4 = rectangles[3, 0];
            double y4 = rectangles[3, 1];
            double width = 0.0f;
            double height = 0.0f;
            double x = 0.0f;
            double y = 0.0f;
            
            //x轴上取最小的数
            if (Math.Abs(x1 - x2) < Double.Epsilon && Math.Abs(x3 - x4) < Double.Epsilon && Math.Abs(x1 - x3) > Double.Epsilon)
            {
                width = Math.Abs(x3 - x1);
                
                x =  x3-x1 > Double.Epsilon? x1:x3;

            }
            else if (Math.Abs(x1 - x2) > Double.Epsilon && Math.Abs(x3 - x4) > Double.Epsilon && Math.Abs(x1 - x3) < Double.Epsilon)
            {
                width = Math.Abs(x2 - x1);
                x = x2 - x1 > Double.Epsilon ? x1 : x2;
            }
            else
            {
                throw new Exception("非法Rectangel！");
            }

            //y轴上取最大的数
            if (Math.Abs(y1 - y2) < Double.Epsilon && Math.Abs(y3 - y4) < Double.Epsilon && Math.Abs(y1 - y3) > Double.Epsilon)
            {
                height = Math.Abs(y3 - y1);
                y = y3 - y1 > Double.Epsilon ? y3 : y1;
            }
            else if (Math.Abs(y1 - y2) > Double.Epsilon && Math.Abs(y3 - y4) > Double.Epsilon && Math.Abs(y1 - y3) < Double.Epsilon)
            {
                height = Math.Abs(y2 - y1);
                y = y2 - y1 > Double.Epsilon ? y2 : y1;
            }
            else
            {
                throw new Exception("非法Rectangel！");
            }


            RectangleX rectangle = new RectangleX((float)x, (float)y,(float) width, (float)height);
            return rectangle;
        }
    }
}
